#include "app_pool.h"

typedef struct
{
    mqd_t mq;           // 队列描述符
    int size;           // 线程的个数
    pthread_t *threads; // 线程池的线程id
    char *mq_name;      // 队列名
} App_Pool_t;
typedef struct
{
    void (*task)(void *);
    void *args;
} Task_t;

void *threadfun(void *);

static App_Pool_t app_pllo;
GateState_t App_Pool_Init(int poolsize)
{
    app_pllo.mq_name = "/pool_queue";
    app_pllo.size = poolsize;
    app_pllo.threads = (pthread_t *)malloc(sizeof(pthread_t) * poolsize);
    // 创建消息队列
    struct mq_attr attr;
    attr.mq_flags = 0;                // 阻塞式读取消息
    attr.mq_maxmsg = 10;              // 队列存储的最大消息数
    attr.mq_msgsize = sizeof(Task_t); // 队列中每条消息的最大字节数

    // 打开消息队列
    app_pllo.mq = mq_open(app_pllo.mq_name, O_RDWR | O_CREAT, 0666, &attr);
    if (app_pllo.mq == -1)
    {
        perror("消息队列创建失败");
        return GATE_ERROR;
    }

    log_info("消息队列创建成功");
    // 创建线程
    for (size_t i = 0; i < poolsize; i++)
    {
        int result = pthread_create(&app_pllo.threads[i], NULL, threadfun, NULL);
        if (result != 0)
        {
            log_error("线程创建失败");
            return GATE_ERROR;
        }
    }
    log_info("线程创建成功");
    log_info("线程池初始化成功");
    return GATE_OK;
}

void App_Pool_Deinit(void)
{

    // 停止线程
    for (size_t i = 0; i < app_pllo.size; i++)
    {
        pthread_cancel(app_pllo.threads[i]);
    }
    // 释放内存
    free(app_pllo.threads);
    app_pllo.threads = NULL;
    // 关闭消息队列
    mq_close(app_pllo.mq);
    app_pllo.mq = -1;
    // 删除消息队列
    mq_unlink(app_pllo.mq_name);
}

void *threadfun(void *)
{
    while (1)
    {
        Task_t task;

        // 接收消息队列发来的消息
        ssize_t len = mq_receive(app_pllo.mq, (char *)&task, sizeof(Task_t), 0);
        if (len == sizeof(Task_t) && task.task)
        {
            task.task(task.args);
        }
    }
}

GateState_t App_Pool_AddFun2Task(void (*task)(void *),void*args){
    if (task==NULL)
    {
       log_error("函数不存在");
       return GATE_ERROR;
    }
    //将函数和参数封装到结构体中
    Task_t task1={
        .task=task,
        .args=args
    }; 
    //向消息队列中发送消息
    if (mq_send(app_pllo.mq,(char*)&task1,sizeof(Task_t),0)==-1)
    {
       perror("消息发送失败");
    }
    // log_info("消息发送成功");

    return GATE_OK;
}